package com.glink.manage.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.glink.common.contants.BaseCodeConstants;
import com.glink.common.exception.GeneralSimpleException;
import com.glink.common.util.BaseCommonUtils;
import com.glink.manage.common.Constants;
import com.glink.manage.domain.*;
import com.glink.manage.dto.vehicle.*;
import com.glink.manage.mapper.VehicleInfoMapper;
import com.glink.manage.service.*;
import com.glink.manage.vo.org.OrgBaseInfoVO;
import com.glink.manage.vo.org.OrgIdRequestDTO;
import com.glink.manage.vo.upload.AttachmentImageUploadVO;
import com.glink.manage.vo.vehicle.VehicleLicensePlateVO;
import com.glink.manage.vo.vehicle.VehiclePageVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;


@Service
@Slf4j
public class VehicleServiceImpl extends ServiceImpl<VehicleInfoMapper, VehicleInfoBean> implements VehicleService {

    @Autowired
    private ParticipatingUnitService participatingUnitService;

    @Autowired
    private AttachmentService attachmentService;

    @Autowired
    @Lazy
    private UserService userService;

    @Autowired
    private OrgService orgService;

    @Autowired
    private BlacklistService blacklistService;

    @Autowired
    private VehicleAccessRelaService vehicleAccessRelaService;

    @Autowired
    @Lazy
    private ConstructionWorkService constructionWorkService;
    
    @Autowired
    @Lazy
    private BarrierGateService barrierGateService;

    /**
     * 添加设备
     *
     * @param vehicleAddDTO 车辆/特征设备信息
     * @return 添加设备状态
     */
    @Override
    @Transactional(value = "transactionManager", propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public String addVehicle(VehicleAddDTO vehicleAddDTO) throws GeneralSimpleException {
        String vehicleId = BaseCommonUtils.generateUUID();
        boolean isSave = true;
        // 核验证件照，如果证件照存在，则不允许登录
        if (StringUtils.isNotBlank(vehicleAddDTO.getLicensePlate())) {
            List<VehicleInfoBean> vehicleInfoBeanList = this.lambdaQuery()
                    .eq(VehicleInfoBean::getLicensePlate, vehicleAddDTO.getLicensePlate())
                    .eq(VehicleInfoBean::getIfDelete, BaseCodeConstants.CodeType_WhetherCode.KEY_WhetherCode02)
                    .list();

            if (CollectionUtils.isNotEmpty(vehicleInfoBeanList)) {
                throwExceptionCardRepeatRoleInfo(vehicleInfoBeanList.get(0).getOrganization());
            }else{
                VehicleInfoBean vehicleInfoBean = this.lambdaQuery()
                        .eq(VehicleInfoBean::getLicensePlate, vehicleAddDTO.getLicensePlate())
                        .last(Constants.LAST_SQL).one();
                if(Objects.nonNull(vehicleInfoBean)){
                    isSave = false;
                    vehicleId = vehicleInfoBean.getObjId();
                }
            }
        }

        // 新增(保存)设备数据
        VehicleInfoBean vehicleInfo = new VehicleInfoBean();
        vehicleInfo.setObjId(vehicleId);
        vehicleInfo.setLicensePlate(vehicleAddDTO.getLicensePlate());
        vehicleInfo.setOwner(vehicleAddDTO.getOwner());
        vehicleInfo.setOrganization(vehicleAddDTO.getOrganization());
        vehicleInfo.setType(vehicleAddDTO.getType());
        vehicleInfo.setAppearancePhoto(vehicleAddDTO.getAppearancePhoto());
        vehicleInfo.setDocument(vehicleAddDTO.getDocument());
        vehicleInfo.setIfDelete(BaseCodeConstants.CodeType_WhetherCode.KEY_WhetherCode02);

        // 尝试保存车辆信息
        boolean status = isSave ? this.save(vehicleInfo) : this.updateById(vehicleInfo);
        if(status){
            return vehicleInfo.getObjId();
        }
        return null;
    }

    /**
     * 删除设备
     *
     * @param vehicleDelDTO 车辆/特种设备主键ID
     * @return 删除设备状态
     */
    @Override
    @Transactional(value = "transactionManager", propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public boolean delVehicle(VehicleDelDTO vehicleDelDTO) throws GeneralSimpleException {

        VehicleInfoBean vehicleInfoBean = findById(vehicleDelDTO.getObjId());
        if (Objects.nonNull(vehicleInfoBean)) {
            vehicleInfoBean.setIfDelete(BaseCodeConstants.CodeType_WhetherCode.KEY_WhetherCode01);
            boolean status = updateById(vehicleInfoBean);
            if(status){
                CompletableFuture.runAsync(() ->  issuedDeleteByObjId(vehicleInfoBean.getObjId(), vehicleInfoBean.getLicensePlate()));
            }
            return status;
        }
        return false;
    }

    /**
     * 加入和移除黑名单
     *
     * @param vehicleBlackListDTO 黑名单信息
     * @return 加入和移除黑名单状态
     */
    @Override
    @Transactional(value = "transactionManager", propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public boolean addBlacklistVehicle(VehicleBlackListDTO vehicleBlackListDTO) throws GeneralSimpleException {
        VehicleInfoBean vehicleInfoBean = findById(vehicleBlackListDTO.getObjId());
        Boolean status = false;
        if (StringUtils.equals(vehicleBlackListDTO.getIfBlacklist(), BaseCodeConstants.CodeType_WhetherCode.KEY_WhetherCode01)) {
            status = blacklistService.saveByIdNumberAndTypeAndUserName(vehicleInfoBean.getLicensePlate(), BaseCodeConstants.CodeType_ApprovalFormType.KEY_ApprovalFormType02, vehicleInfoBean.getOwner(), vehicleInfoBean.getObjId(), BaseCodeConstants.CodeType_AddBlackListActionType.KEY_AddBlackListActionType02,vehicleBlackListDTO.getReason());
        } else if (StringUtils.equals(vehicleBlackListDTO.getIfBlacklist(), BaseCodeConstants.CodeType_WhetherCode.KEY_WhetherCode02)) {
            status = blacklistService.delByIdNumberAndType(vehicleInfoBean.getLicensePlate(), BaseCodeConstants.CodeType_ApprovalFormType.KEY_ApprovalFormType02);
        }
        if(status){
            CompletableFuture.runAsync(() ->  barrierGateService.issuedCarByVehicleId(vehicleInfoBean.getObjId()));
        }
        return status;
    }


    private VehicleInfoBean findById(String vehicleObjId) throws GeneralSimpleException {
        VehicleInfoBean vehicleInfoBean = this.getById(vehicleObjId);
        if (Objects.isNull(vehicleInfoBean)) {
            throw new GeneralSimpleException("400051", vehicleObjId);
        }
        return vehicleInfoBean;
    }

    /**
     * 车辆和特种设配黑名单页面查询
     *
     * @param vehicleFindDTO 查询条件
     * @return 车辆/特种设备信息
     */
    @Override
    @Transactional(value = "transactionManager", propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public IPage<VehiclePageVO> findVehicleBlackList(VehicleFindDTO vehicleFindDTO) throws GeneralSimpleException {
        return findVehicle(vehicleFindDTO, true);
    }

    /**
     * 分页查询
     *
     * @param vehicleFindDTO 查询条件
     * @return 查询信息
     */
    @Override
    @Transactional(value = "transactionManager", propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public IPage<VehiclePageVO> findVehicle(VehicleFindDTO vehicleFindDTO) throws GeneralSimpleException {
        return findVehicle(vehicleFindDTO, false);
    }

    // 分页查询-方法实现
    private IPage<VehiclePageVO> findVehicle(VehicleFindDTO vehicleFindDTO, boolean isBlacklist) throws GeneralSimpleException {

        // -----------------根据权限查询数据---------------------------------
        // 查询权限内的单位
        boolean headOffice = userService.checkHeadOffice();
        List<String> orgIdList = null;
        List<String> vehicleIdList = Lists.newArrayList();
        if (!headOffice) {
            boolean projectDepartment = userService.checkProjectDepartment();
            if(projectDepartment){
                orgIdList = orgService.getDataPermissionOrgId();
            }else{
                // 是否总包单位管理员
                boolean generalContractingUnit = userService.checkGeneralContractingUnit();
                if(generalContractingUnit){
                    // 总包单位管理员，查询自己管辖工程下的参建单位
                    List<String> workIdList = constructionWorkService.findGeneralContractingUnitAccessWorkId();
                    if(CollectionUtils.isNotEmpty(workIdList)){
                        orgIdList = Lists.newArrayList();
                        String orgId = BaseCommonUtils.extractOrdIdByToken();
                        orgIdList.add(orgId);
                        
                        List<String> participatingUnitOrgIdList = constructionWorkService.findGeneralContractingUnitParticipatingUnitObjIdByObjIdIn(workIdList);

                        // 存在参建单位，则查询哪些用户准入了工程
                        List<VehicleInfoBean> vehicleInfoBeanList = this.lambdaQuery().in(VehicleInfoBean::getOrganization, participatingUnitOrgIdList)
                                .eq(VehicleInfoBean::getIfDelete, BaseCodeConstants.CodeType_WhetherCode.KEY_WhetherCode02)
                                .list();
                        if(CollectionUtils.isNotEmpty(vehicleInfoBeanList)){
                            // 参建单位人员信息
                            List<String> participatingUnitVehicleIdList = vehicleInfoBeanList.stream().map(VehicleInfoBean::getObjId).collect(Collectors.toList());

                            // 查询准入的工程的人员信息
                            List<VehicleAccessRelaBean> accessRelaBeanList = vehicleAccessRelaService.lambdaQuery()
                                    .in(VehicleAccessRelaBean::getVehicleId, participatingUnitVehicleIdList)
                                    .in(VehicleAccessRelaBean::getConstructionWorkObjId, workIdList)
                                    .list();
                            if(org.apache.commons.collections.CollectionUtils.isNotEmpty(accessRelaBeanList)){
                                vehicleIdList = accessRelaBeanList.stream().map(VehicleAccessRelaBean::getVehicleId).collect(Collectors.toList());
                            }
                        }
                    }
                }
                
                if(CollectionUtils.isEmpty(orgIdList)){
                    orgIdList = orgService.getDataPermissionOrgId();
                }
            }
        }

        if (!headOffice && CollectionUtils.isEmpty(orgIdList)) {
            log.info("车辆管理：单位信息有误，即不是项目部也不是参建单位");
            return new Page<>(vehicleFindDTO.getPage(), vehicleFindDTO.getSize());
        }
        // -----------------end---------------------------------

        // -----------------黑名单数据范围限制---------------------------------
        List<String> blacklistLicensePlates = blacklistService.findIdNumberByType(BaseCodeConstants.CodeType_ApprovalFormType.KEY_ApprovalFormType02);
        blacklistLicensePlates = (blacklistLicensePlates == null) ? Lists.newArrayList() : blacklistLicensePlates;

        if (isBlacklist && CollectionUtils.isEmpty(blacklistLicensePlates)) {
            log.info("车辆管理：黑名单查询，但黑名单数据不存在");
            return new Page<>(vehicleFindDTO.getPage(), vehicleFindDTO.getSize());
        }
        // -----------------黑名单过滤结束---------------------------------

        // 分页对象
        Page<VehicleInfoBean> page = new Page<>(vehicleFindDTO.getPage(), vehicleFindDTO.getSize());

        // 查询条件
        LambdaQueryWrapper<VehicleInfoBean> queryWrapper = new LambdaQueryWrapper<>();
        // 根据权限范围过滤数据
        List<String> finalOrgIdList = orgIdList;
        List<String> finalVehicleIdList = vehicleIdList;
        queryWrapper.and(!headOffice && CollectionUtils.isNotEmpty(orgIdList), 
                w -> w.in(VehicleInfoBean::getOrganization, finalOrgIdList)
                        .or()
                        .in(CollectionUtils.isNotEmpty(finalVehicleIdList), VehicleInfoBean::getObjId, finalVehicleIdList));
        // 根据是否黑名单过滤数据
        queryWrapper.in(isBlacklist, VehicleInfoBean::getLicensePlate, blacklistLicensePlates);
        queryWrapper.in(!isBlacklist, VehicleInfoBean::getIfDelete, BaseCodeConstants.CodeType_WhetherCode.KEY_WhetherCode02);

        // 根据筛选条件过滤
        if (StringUtils.isNotEmpty(vehicleFindDTO.getSearchStr())) {
            queryWrapper.and(w -> w.like(VehicleInfoBean::getLicensePlate, vehicleFindDTO.getSearchStr())
                    .or()
                    .like(VehicleInfoBean::getOwner, vehicleFindDTO.getSearchStr()));
        }
        if (StringUtils.isNotEmpty(vehicleFindDTO.getOrganization())) {
            queryWrapper.eq(VehicleInfoBean::getOrganization, vehicleFindDTO.getOrganization());
        }

        // 排序
        queryWrapper
                .orderByAsc(VehicleInfoBean::getOrganization)
                .orderByAsc(VehicleInfoBean::getLicensePlate)
                .orderByAsc(VehicleInfoBean::getObjId);

        // 执行分页查询
        IPage<VehicleInfoBean> vehiclePage = this.page(page, queryWrapper);

        // -----------------组装结果---------------------------------
        IPage<VehiclePageVO> vehiclePageVOIPage = vehiclePage.convert(vehicleBean -> {
            VehiclePageVO vehiclePageVO = new VehiclePageVO();
            BeanUtils.copyProperties(vehicleBean, vehiclePageVO);

            // 设置所属单位名称
            if (StringUtils.isNotBlank(vehicleBean.getOrganization())) {
                String orgName = orgService.findOrgNameByOrgId(vehicleBean.getOrganization());
                vehiclePageVO.setOrganizationName(orgName);
            }

            // 设置是否黑名单
            boolean isBlacklistFlag = blacklistService.checkBlackListByIdNumberAndType(vehicleBean.getLicensePlate(), BaseCodeConstants.CodeType_ApprovalFormType.KEY_ApprovalFormType02);
            if (isBlacklistFlag) {
                vehiclePageVO.setIfBlacklist(BaseCodeConstants.CodeType_WhetherCode.KEY_WhetherCode01);
                
                //加入黑名单原因
                String reason = blacklistService.findReasonByIdNumberAndType(vehicleBean.getLicensePlate(), BaseCodeConstants.CodeType_ApprovalFormType.KEY_ApprovalFormType02);
                if(StringUtils.isNotBlank(reason)){
                    vehiclePageVO.setReason(reason);
                }
            } else {
                vehiclePageVO.setIfBlacklist(BaseCodeConstants.CodeType_WhetherCode.KEY_WhetherCode02);
            }

            // 处理证件照，返回文件名称
            if (StringUtils.isNotBlank(vehicleBean.getDocument())) {
                List<String> imageIdList = Arrays.asList(vehicleBean.getDocument().split(",", -1));
                if (CollectionUtils.isNotEmpty(imageIdList)) {
                    Map<String, String> imageMap = attachmentService.findImageIdByImageIdIn(imageIdList);
                    if (Objects.nonNull(imageMap)) {
                        List<AttachmentImageUploadVO> documentList = Lists.newArrayList();
                        imageMap.forEach((k, v) -> {
                            AttachmentImageUploadVO uploadVO = new AttachmentImageUploadVO();
                            uploadVO.setId(k);
                            uploadVO.setName(v);
                            documentList.add(uploadVO);
                        });
                        vehiclePageVO.setDocumentList(documentList);
                    }
                }
            }
            return vehiclePageVO;
        });

        return vehiclePageVOIPage;
    }

    /**
     * 解除黑名单
     *
     * @param vehicleIdDTO ID
     * @return 解除状态
     */
    @Override
    @Transactional(value = "transactionManager", propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public boolean liftBlacklistVehicle(VehicleIdDTO vehicleIdDTO) throws GeneralSimpleException {
        VehicleInfoBean vehicleInfoBean = findById(vehicleIdDTO.getObjId());
        Boolean status = blacklistService.delByIdNumberAndType(vehicleInfoBean.getLicensePlate(), BaseCodeConstants.CodeType_ApprovalFormType.KEY_ApprovalFormType02);
        if(status){
            CompletableFuture.runAsync(() ->  barrierGateService.issuedCarByVehicleId(vehicleInfoBean.getObjId()));
        }
        return status;

    }

    /**
     * 根据车牌号查询用户信息
     *
     * @param vehicleLicensePlateDTO 车牌号
     * @return 车牌/特种设备信息
     */
    @Override
    public VehicleLicensePlateVO findByCar(VehicleLicensePlateDTO vehicleLicensePlateDTO) throws GeneralSimpleException {
        VehicleLicensePlateVO vehicleLicensePlateVO = new VehicleLicensePlateVO();

        //筛选车牌号的装成列表
        List<VehicleInfoBean> vehicleInfoBeanList = this.lambdaQuery()
                .eq(VehicleInfoBean::getLicensePlate, vehicleLicensePlateDTO.getLicensePlate())
                .list();
        String document = "";
        if (CollectionUtils.isNotEmpty(vehicleInfoBeanList)) {
            VehicleInfoBean vehicleInfoBean = vehicleInfoBeanList.get(0);

            // 如果当前人员信息符合当前用户权限范围内，则返回用户信息，否则不给查看

            // -----------------根据权限查询数据---------------------------------

            // 查询权限内的单位
            String orgId = BaseCommonUtils.extractOrdIdByToken();
            if (StringUtils.isBlank(orgId)) {
                log.info("单位信息不存在");
                throw new GeneralSimpleException("100003");
            }
            // 是否查询全部
            boolean headOffice = userService.checkHeadOffice();
            List<String> orgIdList = null;
            if (!headOffice) {
                orgIdList = orgService.getDataPermissionOrgId();
            }
            // -----------------end---------------------------------

            // 权限判断：用户是否有权限查看该车辆
            if (!headOffice && !orgIdList.contains(vehicleInfoBean.getOrganization())) {

                throwExceptionCardRepeatRoleInfo(vehicleInfoBean.getOrganization());
            }
            //车牌号对应的用户，和当前登录的用户，不是同一个单位范围，不允许查看
            BeanUtils.copyProperties(vehicleInfoBean, vehicleLicensePlateVO);

            document = vehicleInfoBean.getDocument();
        } else {
            vehicleInfoBeanList = this.lambdaQuery().eq(VehicleInfoBean::getLicensePlate, vehicleLicensePlateDTO.getLicensePlate())
                    .orderByDesc(VehicleInfoBean::getCreateTime)
                    .orderByDesc(VehicleInfoBean::getObjId)
                    .list();
            if (org.apache.commons.collections.CollectionUtils.isNotEmpty(vehicleInfoBeanList)) {
                VehicleInfoBean vehicleInfoBean = vehicleInfoBeanList.get(0);
                BeanUtils.copyProperties(vehicleInfoBean, vehicleLicensePlateVO);
                vehicleLicensePlateVO.setOrganization(null);
                document = vehicleInfoBean.getDocument();
            }
        }

        // 处理证件照，返回文件名称
        if (StringUtils.isNotBlank(document)) {
            // 使用逗号 , 分割 document 字符串，并将其转换为一个 List<String> 列表 imageIdList。-1 参数表示不限制分割次数。
            List<String> imageIdList = Arrays.asList(document.split(",", -1));
            if (CollectionUtils.isNotEmpty(imageIdList)) {
                // 调用 attachmentService 的 findImageIdByImageIdIn 方法，传入 imageIdList，获取一个 Map<String, String> 类型的 imageMap，其中键是图片ID，值是图片名称。
                Map<String, String> imageMap = attachmentService.findImageIdByImageIdIn(imageIdList);
                if (Objects.nonNull(imageMap)) {
                    List<AttachmentImageUploadVO> documentList = Lists.newArrayList();
                    imageMap.forEach((k, v) -> {
                        AttachmentImageUploadVO uploadVO = new AttachmentImageUploadVO();
                        uploadVO.setId(k);
                        uploadVO.setName(v);
                        documentList.add(uploadVO);
                    });
                    vehicleLicensePlateVO.setDocumentList(documentList);
                }
            }
        }

        //设置黑名单信息,根据车牌号，状态查询类型 2
        boolean ifBlackList = blacklistService.checkBlackListByIdNumberAndType(vehicleLicensePlateDTO.getLicensePlate(), BaseCodeConstants.CodeType_ApprovalFormType.KEY_ApprovalFormType02);
        if (ifBlackList) {
            vehicleLicensePlateVO.setIfBlacklist(BaseCodeConstants.CodeType_WhetherCode.KEY_WhetherCode01);
            vehicleLicensePlateVO.setLicensePlate(vehicleLicensePlateDTO.getLicensePlate());
        }
        return vehicleLicensePlateVO;
    }


    /**
     * 抛异常-证件照重复角色信息
     *
     * @param vehicleOrgId 人员单位
     * @throws GeneralSimpleException 异常信息
     */
    private void throwExceptionCardRepeatRoleInfo(String vehicleOrgId) throws GeneralSimpleException {
        OrgBaseInfoVO orgBaseInfoVO = orgService.findById(new OrgIdRequestDTO(vehicleOrgId));
        String orgName = "";
        if (Objects.nonNull(orgBaseInfoVO)) {
            orgName = orgBaseInfoVO.getName();
            if (StringUtils.isNotBlank(orgBaseInfoVO.getPid())) {
                orgBaseInfoVO = orgService.findById(new OrgIdRequestDTO(orgBaseInfoVO.getPid()));
                if (Objects.nonNull(orgBaseInfoVO)) {
                    orgName = orgBaseInfoVO.getName() + "-" + orgName;
                }
            }
        } else {
            // 参建单位
            if (StringUtils.isNotBlank(vehicleOrgId)) {
                String name = participatingUnitService.findNameByObjId(vehicleOrgId);
                if (StringUtils.isNotBlank(name)) {
                    orgName = "参建单位-" + name;
                }
            }
        }

        if (StringUtils.isBlank(orgName)) {
            orgName = "单位信息不存在";
        }

        throw new GeneralSimpleException("400045", orgName);
    }


    /**
     * 根据objid查
     *
     * @param vehicleIdDTO 主键id
     * @return 车辆/特种设备信息
     */
    @Override
    public VehicleLicensePlateVO findById(VehicleDelDTO vehicleIdDTO) throws GeneralSimpleException {
        VehicleInfoBean vehicleInfoBean = findById(vehicleIdDTO.getObjId());
        VehicleLicensePlateVO vehicleIdVO = new VehicleLicensePlateVO();

        BeanUtils.copyProperties(vehicleInfoBean, vehicleIdVO);

        // 是否黑名单
        boolean ifBlacklist = blacklistService.checkBlackListByIdNumberAndType(vehicleInfoBean.getLicensePlate(), BaseCodeConstants.CodeType_ApprovalFormType.KEY_ApprovalFormType02);
        if (ifBlacklist) {
            vehicleIdVO.setIfBlacklist(BaseCodeConstants.CodeType_WhetherCode.KEY_WhetherCode01);
        } else {
            vehicleIdVO.setIfBlacklist(BaseCodeConstants.CodeType_WhetherCode.KEY_WhetherCode02);
        }

        // 处理证件照，返回文件名称
        if (StringUtils.isNotBlank(vehicleInfoBean.getDocument())) {
            // 使用逗号 , 分割 document 字符串，并将其转换为一个 List<String> 列表 imageIdList。-1 参数表示不限制分割次数。
            List<String> imageIdList = Arrays.asList(vehicleInfoBean.getDocument().split(",", -1));
            if (CollectionUtils.isNotEmpty(imageIdList)) {
                // 调用 attachmentService 的 findImageIdByImageIdIn 方法，传入 imageIdList，获取一个 Map<String, String> 类型的 imageMap，其中键是图片ID，值是图片名称。
                Map<String, String> imageMap = attachmentService.findImageIdByImageIdIn(imageIdList);
                if (Objects.nonNull(imageMap)) {
                    List<AttachmentImageUploadVO> documentList = Lists.newArrayList();
                    imageMap.forEach((k, v) -> {
                        AttachmentImageUploadVO uploadVO = new AttachmentImageUploadVO();
                        uploadVO.setId(k);
                        uploadVO.setName(v);
                        documentList.add(uploadVO);
                    });
                    vehicleIdVO.setDocumentList(documentList);
                }
            }
        }

        return vehicleIdVO;
    }

    /**
     * 保存准入
     *
     * @param vehicleId             车辆/特种设备ID
     * @param constructionWorkObjId 工程ID
     * @param cycleStart            准入周期开始
     * @param cycleEnd              准入周期结束
     */
    @Override
    @Transactional(value = "transactionManager", propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void saveAccessWork(String vehicleId, String constructionWorkObjId, Date cycleStart, Date cycleEnd, String accessMonadObjId) {
        VehicleInfoBean vehicleInfoBean = this.getById(vehicleId);
        if (Objects.nonNull(vehicleInfoBean)) {
            VehicleAccessRelaBean vehicleAccessRelaBean = new VehicleAccessRelaBean();
            vehicleAccessRelaBean.setObjId(BaseCommonUtils.generateUUID());
            vehicleAccessRelaBean.setVehicleId(vehicleId);
            vehicleAccessRelaBean.setConstructionWorkObjId(constructionWorkObjId);
            vehicleAccessRelaBean.setCycleStart(cycleStart);
            vehicleAccessRelaBean.setCycleEnd(cycleEnd);
            vehicleAccessRelaBean.setAccessMonadObjId(accessMonadObjId);
            boolean status = vehicleAccessRelaService.save(vehicleAccessRelaBean);
            if(status){
                barrierGateService.issuedCarAdd(vehicleInfoBean.getLicensePlate(), cycleStart, cycleEnd, constructionWorkObjId);
            }
        }
    }
    


    /**
     * 检查黑名单
     *
     * @param associationObjId 用户ID
     * @return 状态
     */
    @Override
    public boolean checkBlackList(String associationObjId) throws GeneralSimpleException {
        VehicleInfoBean vehicleInfoBean = findById(associationObjId);
        return blacklistService.checkBlackListByIdNumberAndType(vehicleInfoBean.getLicensePlate(), BaseCodeConstants.CodeType_ApprovalFormType.KEY_ApprovalFormType02);
    }

    /**
     * 更新车辆/特种设备信息
     *
     * @param vehicleUpdateDTO 更新信息
     * @return 状态
     */
    @Override
    @Transactional(value = "transactionManager", propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public boolean updateVehicle(VehicleUpdateDTO vehicleUpdateDTO) throws GeneralSimpleException {
        // 根据id 找到对应的数据
        VehicleInfoBean vehicleInfoBean = findById(vehicleUpdateDTO.getObjId());

        // 只更新变动的值
        if (vehicleInfoBean != null) {
            vehicleInfoBean.setDocument(vehicleUpdateDTO.getDocument());
            vehicleInfoBean.setLicensePlate(vehicleUpdateDTO.getLicensePlate());
            vehicleInfoBean.setOrganization(vehicleUpdateDTO.getOrganization());
            vehicleInfoBean.setAppearancePhoto(vehicleUpdateDTO.getAppearancePhoto());
            vehicleInfoBean.setType(vehicleUpdateDTO.getType());
            vehicleInfoBean.setOwner(vehicleUpdateDTO.getOwner());

            return this.updateById(vehicleInfoBean);
        }

        return false;
    }

    /**
     * 根据车牌查询车辆信息
     *
     * @param plateNum 车牌
     * @return 车辆信息
     */
    @Override
    public VehicleInfoBean findByLicensePlate(String plateNum) {
        return this.lambdaQuery().eq(VehicleInfoBean::getLicensePlate, plateNum).last(Constants.LAST_SQL).one();
    }

    /**
     * 根据参建单位和工程查询准入的车辆
     *
     * @param constructionWorkObjId  工程ID
     * @param participatingUnitObjId 参建单位ID
     * @return 准入人员名称
     */
    @Override
    public List<String> findAccessLicensePlateByWorkObjIdAndUnitObjId(String constructionWorkObjId, String participatingUnitObjId) {
        String nowDate = BaseCommonUtils.DATE_FORMAT_DAY_3.format(new Date());
        return this.baseMapper.findAccessLicensePlateByWorkObjIdAndUnitObjId(constructionWorkObjId, participatingUnitObjId, nowDate);
    }

    /**
     * 更新用户准入周期
     *
     * @param constructionWorkObjId  工程ID
     * @param participatingUnitObjId 参建单位ID
     * @return 更新状态
     */
    @Override
    @Transactional(value = "transactionManager", propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public boolean updateAccessCycleByWorkObjIdAndUnitObjId(String constructionWorkObjId, String participatingUnitObjId) {
        // 准入周期还没开始的，则删除准入
        vehicleAccessRelaService.delAccessByWorkObjIdAndUnitObjIdAndCycleStartGt(constructionWorkObjId, participatingUnitObjId, BaseCommonUtils.DATE_FORMAT_DAY_3.format(new Date()));

        // 正在准入，则更新准入时间
        vehicleAccessRelaService.updateAccessCycleEndByWorkObjIdAndUnitObjIdAndCycleStartGtAndCycleEndLt(constructionWorkObjId, participatingUnitObjId, BaseCommonUtils.DATE_FORMAT_DAY_3.format(new Date()));

        return true;
    }

    /**
     * 根据车辆类型统计车辆数
     *
     * @param carType 车辆类型
     * @param vehicleIdList 工程ID
     * @return 车辆类型
     */
    @Override
    public Integer countByTypeAndObjIdInAndLicensePlateIn(String carType, List<String> vehicleIdList, Set<String> licensePlateList) {
        return this.lambdaQuery().eq(VehicleInfoBean::getType, carType)
                .eq(VehicleInfoBean::getIfDelete, BaseCodeConstants.CodeType_WhetherCode.KEY_WhetherCode02)
                .in(VehicleInfoBean::getObjId, vehicleIdList)
                .in(VehicleInfoBean::getLicensePlate, licensePlateList)
                .count();
    }

    @Override
    public Integer countByTypeAndLicensePlateIn(String carType, Set<String> licensePlateList) {
        return this.lambdaQuery().eq(VehicleInfoBean::getType, carType)
                .eq(VehicleInfoBean::getIfDelete, BaseCodeConstants.CodeType_WhetherCode.KEY_WhetherCode02)
                .in(VehicleInfoBean::getLicensePlate, licensePlateList)
                .count();
    }

    /**
     * 根据工程ID查询未同步的车牌号
     *
     * @param devSno 设备号
     * @param workObjId 工程ID
     * @return 车牌准入信息
     */
    @Override
    public List<VehicleSyncDTO> findLicensePlateByWorkIdAndNotSync(String devSno, String workObjId, Date date) {
        ConstructionWorkBean constructionWorkBean = constructionWorkService.getById(workObjId);
        if(Objects.nonNull(constructionWorkBean)) {
            if (StringUtils.isNotBlank(constructionWorkBean.getProjectDepartmentObjId())) {
                try {
                    List<String> orgIdList = orgService.findOrgTreeIdByOrgId(constructionWorkBean.getProjectDepartmentObjId());
                    List<VehicleSyncDTO> allVehicleSyncDTO = Lists.newArrayList();

                    // 项目部的准入
                    List<VehicleSyncDTO> department = this.baseMapper.findLicensePlateIdByWorkIdAndNotSyncByDepartment(devSno, orgIdList,
                            BaseCodeConstants.CodeType_ApprovalFormType.KEY_ApprovalFormType02,
                            Constants.CAR_SYNC_LIMIT);
                    if(CollectionUtils.isNotEmpty(department)){
                        allVehicleSyncDTO.addAll(department);
                    }

                    // 装载参建单位的准入
                    if(allVehicleSyncDTO.size() < Constants.CAR_SYNC_LIMIT){
                        List<VehicleSyncDTO> participatingUnit = this.baseMapper.findLicensePlateIdByWorkIdAndNotSyncByParticipatingUnit(
                                devSno, workObjId, date,
                                BaseCodeConstants.CodeType_ApprovalFormType.KEY_ApprovalFormType02,
                                Constants.CAR_SYNC_LIMIT);
                        if(CollectionUtils.isNotEmpty(participatingUnit)){
                            int size = Constants.CAR_SYNC_LIMIT - allVehicleSyncDTO.size();
                            if(participatingUnit.size() < size){
                                allVehicleSyncDTO.addAll(participatingUnit);
                            }else{
                                allVehicleSyncDTO.addAll(participatingUnit.subList(0, size));
                            }
                        }
                    }

                    // 临时准入
                    if(allVehicleSyncDTO.size() < Constants.CAR_SYNC_LIMIT) {

                        List<String> licensePlateList = allVehicleSyncDTO.stream().map(VehicleSyncDTO::getLicensePlate).collect(Collectors.toList());

                        List<VehicleSyncDTO> temporary = this.baseMapper.findLicensePlateIdByWorkIdAndNotSyncByTemporary(devSno, workObjId, date,
                                BaseCodeConstants.CodeType_AdmissionType.KEY_AdmissionType02,
                                BaseCodeConstants.CodeType_AccessStatus.KEY_AccessStatus01,
                                BaseCodeConstants.CodeType_ApprovalFormType.KEY_ApprovalFormType04,
                                licensePlateList,
                                Constants.CAR_SYNC_LIMIT);
                        if(CollectionUtils.isNotEmpty(temporary)){
                            List<VehicleSyncDTO> temp = Lists.newArrayList();
                            List<String> existList = Lists.newArrayList();
                            temporary.forEach(t -> {
                                if(!existList.contains(t.getLicensePlate())){
                                    temp.add(t);
                                    existList.add(t.getLicensePlate());
                                }
                            });
                            
                            int size = Constants.CAR_SYNC_LIMIT - allVehicleSyncDTO.size();
                            if(temp.size() < size){
                                allVehicleSyncDTO.addAll(temp);
                            }else{
                                allVehicleSyncDTO.addAll(temp.subList(0, size));
                            }
                        }
                    }

                    return allVehicleSyncDTO;
                } catch (GeneralSimpleException e) {
                    log.error("查询准入车牌信息异常", e);
                }
            }
        }
        
        return null;
    }

    /**
     * 根据工程ID查询未同步的车牌号
     *
     * @param devSno 设备号
     * @param workObjId 工程ID
     * @return 车牌准入信息
     */
    @Override
    public List<VehicleSyncDTO> findLicensePlateByWorkId(String devSno, String workObjId, List<String> orgIdList, Date date, boolean sync) {
        ConstructionWorkBean constructionWorkBean = constructionWorkService.getById(workObjId);
        if(Objects.nonNull(constructionWorkBean)) {
            if (StringUtils.isNotBlank(constructionWorkBean.getProjectDepartmentObjId())) {
                List<VehicleSyncDTO> allVehicleSyncDTO = Lists.newArrayList();

                // 项目部的准入
                List<VehicleSyncDTO> department = this.baseMapper.findLicensePlateIdByWorkIdByDepartment(devSno, orgIdList,
                        BaseCodeConstants.CodeType_ApprovalFormType.KEY_ApprovalFormType02, sync);
                if(CollectionUtils.isNotEmpty(department)){
                    allVehicleSyncDTO.addAll(department);
                }

                // 装载参建单位的准入
                List<VehicleSyncDTO> participatingUnit = this.baseMapper.findLicensePlateIdByWorkIdByParticipatingUnit(
                        devSno, workObjId, date,
                        BaseCodeConstants.CodeType_ApprovalFormType.KEY_ApprovalFormType02, sync);
                if(CollectionUtils.isNotEmpty(participatingUnit)){
                    allVehicleSyncDTO.addAll(participatingUnit);
                }

                // 临时准入
                List<String> licensePlateList = allVehicleSyncDTO.stream().map(VehicleSyncDTO::getLicensePlate).collect(Collectors.toList());

                List<VehicleSyncDTO> temporary = this.baseMapper.findLicensePlateIdByWorkIdByTemporary(devSno, workObjId, date,
                        BaseCodeConstants.CodeType_AdmissionType.KEY_AdmissionType02,
                        BaseCodeConstants.CodeType_AccessStatus.KEY_AccessStatus01,
                        BaseCodeConstants.CodeType_ApprovalFormType.KEY_ApprovalFormType04,
                        licensePlateList, sync);
                if(CollectionUtils.isNotEmpty(temporary)){
                    allVehicleSyncDTO.addAll(temporary);
                }

                return allVehicleSyncDTO;
            }
        }

        return null;
    }


    /**
     * 下发删除车辆名单
     * @param vehicleId 车辆ID
     * @param licensePlate 车牌
     */
    public void issuedDeleteByObjId(String vehicleId, String licensePlate) {
        List<String> workIdList = vehicleAccessRelaService.findWorkIdByPersonId(vehicleId);
        if(CollectionUtils.isNotEmpty(workIdList)){
            barrierGateService.issuedCarDeleteByLicensePlate(licensePlate, workIdList);
        }
    }
}
